<?php

class Quad_Curl {
	
	public static $defaultOptions = array(
		CURLOPT_RETURNTRANSFER => true,
		CURLOPT_FOLLOWLOCATION => true,
		CURLOPT_SSL_VERIFYPEER => false,
	);
	
	protected $_options = array();
	protected $_url;
	protected $_headers = array();
	protected $_post;
	protected $_get;
	protected $_cookie;
	
	public function __construct($url, $options = array()) {
		$this->_url = $url;
		$this->setOptions(self::$defaultOptions);
		$this->setOptions($options);
	}
	
	public function getInstance($url, $options = array()) {
		return new self($url, $options);
	}
	
	public function getUrl() {
		return $this->_url;
	}
	
	public function setUrl($url) {
		$this->_url = $url;
		return $this;
	}
	
	public function setOption($name, $value) {
		if ($name == CURLOPT_HTTPHEADER) {
			$this->addHeader($value);
		}
		else {
			$this->_options[$name] = $value;
		}
		return $this;
	}
	
	public function setOptions($values) {
		foreach ($values as $name => $value) {
			$this->setOption($name, $value);
		}
		return $this;
	}
	
	public function clearHeaders() {
		$this->_headers = array();
		return $this;
	}
	
	public function addHeader($value) {
		$this->_headers[] = $value;
		return $this;
	}
	
	public function addHeaders($values) {
		foreach ($values as $value) {
			$this->addHeader($value);
		}
		return $this;		
	}
	
	public function setPost($values) {		
		$this->_post = $values;			
		return $this;	
	}
	
	public function getPost() {
		$this->_post = $values;
	}
	
	public function setGET($values) {
		$this->_get = $values;
		return $this;
	}
	
	public function getGET() {
		return $this->_get;
	}
	
	public function setCookies($values) {
		$this->_cookie = $values;
		return $this;
	}
	
	public function getCookies() {
		return $this->_cookie;
	}
	
	public function exec() {
		if (count($this->_post)) {
			$this->setOption(CURLOPT_POST, 1);
			$this->setOption(CURLOPT_POSTFIELDS, http_build_query($this->_post));
		}
		$url = $this->_url;
		if (count($this->_get)) {
			$url .= '?' . http_build_query($this->_get);
		}
		if (count($this->_cookie)) {
			$this->setOption(CURLOPT_COOKIE, http_build_query($this->_cookie, '', '; '));
		}
		
		$handle = curl_init($url);
		if (count($this->_headers)) {
			$ok = curl_setopt($handle, CURLOPT_HTTPHEADER, $this->_headers);
		}
		$ok = curl_setopt_array($handle, $this->_options);
		
		$response = curl_exec($handle);
		$resp = new Quad_Curl_Response($this, $response, $handle);
		@curl_close($handle);
		return $resp;
	}
	
	public function copy() {
		return clone $this;
	}
	
	public function version() {
		return curl_version();
	}
	
	# super long list of constants that are alternates of CURL* constants 
	// http://php.net/manual/en/curl.constants.php accessed as of PHP 5.2.11
	const OPT_AUTOREFERER  = CURLOPT_AUTOREFERER ;
	// ^ Available since PHP 5.1.0 
	
	const OPT_COOKIESESSION  = CURLOPT_COOKIESESSION ;
	// ^ Available since PHP 5.1.0 
	
	const OPT_DNS_USE_GLOBAL_CACHE  = CURLOPT_DNS_USE_GLOBAL_CACHE ;
	
	const OPT_DNS_CACHE_TIMEOUT  = CURLOPT_DNS_CACHE_TIMEOUT ;
	
	const OPT_FTP_SSL  = CURLOPT_FTP_SSL ;
	// ^ Available since PHP 5.2.0 
	
	const FTPSSL_TRY  = CURLFTPSSL_TRY ;
	// ^ Available since PHP 5.2.0 
	
	const FTPSSL_ALL  = CURLFTPSSL_ALL ;
	// ^ Available since PHP 5.2.0 
	
	const FTPSSL_CONTROL  = CURLFTPSSL_CONTROL ;
	// ^ Available since PHP 5.2.0 
	
	const FTPSSL_NONE  = CURLFTPSSL_NONE ;
	// ^ Available since PHP 5.2.0 
	
	const OPT_PRIVATE  = CURLOPT_PRIVATE ;
	// ^ Available since PHP 5.2.4 
	
	const OPT_FTPSSLAUTH  = CURLOPT_FTPSSLAUTH ;
	// ^ Available since PHP 5.1.0 
	
	const OPT_PORT  = CURLOPT_PORT ;
	
	const OPT_FILE  = CURLOPT_FILE ;
	
	const OPT_INFILE  = CURLOPT_INFILE ;
	
	const OPT_INFILESIZE  = CURLOPT_INFILESIZE ;
	
	const OPT_URL  = CURLOPT_URL ;
	
	const OPT_PROXY  = CURLOPT_PROXY ;
	
	const OPT_VERBOSE  = CURLOPT_VERBOSE ;
	
	const OPT_HEADER  = CURLOPT_HEADER ;
	
	const OPT_HTTPHEADER  = CURLOPT_HTTPHEADER ;
	
	const OPT_NOPROGRESS  = CURLOPT_NOPROGRESS ;
	
	const OPT_NOBODY  = CURLOPT_NOBODY ;
	
	const OPT_FAILONERROR  = CURLOPT_FAILONERROR ;
	
	const OPT_UPLOAD  = CURLOPT_UPLOAD ;
	
	const OPT_POST  = CURLOPT_POST ;
	
	const OPT_FTPLISTONLY  = CURLOPT_FTPLISTONLY ;
	
	const OPT_FTPAPPEND  = CURLOPT_FTPAPPEND ;
	
	const OPT_FTP_CREATE_MISSING_DIRS  = CURLOPT_FTP_CREATE_MISSING_DIRS ;
	
	const OPT_NETRC  = CURLOPT_NETRC ;
	
	const OPT_FOLLOWLOCATION  = CURLOPT_FOLLOWLOCATION ;
	// ^ This constant is not available when open_basedir or safe_mode are enabled. 
	
	const OPT_FTPASCII  = CURLOPT_FTPASCII ;
	
	const OPT_PUT  = CURLOPT_PUT ;
	
	const OPT_MUTE  = CURLOPT_MUTE ;
	
	const OPT_USERPWD  = CURLOPT_USERPWD ;
	
	const OPT_PROXYUSERPWD  = CURLOPT_PROXYUSERPWD ;
	
	const OPT_RANGE  = CURLOPT_RANGE ;
	
	const OPT_TIMEOUT  = CURLOPT_TIMEOUT ;
	
	const OPT_TIMEOUT_MS  = CURLOPT_TIMEOUT_MS ;
	
	const OPT_TCP_NODELAY  = CURLOPT_TCP_NODELAY ;
	// ^ Available since PHP 5.2.1 
	
	const OPT_POSTFIELDS  = CURLOPT_POSTFIELDS ;
	
	const OPT_PROGRESSFUNCTION  = CURLOPT_PROGRESSFUNCTION ;
	// ^ Available since PHP 5.3.0 
	
	const OPT_REFERER  = CURLOPT_REFERER ;
	
	const OPT_USERAGENT  = CURLOPT_USERAGENT ;
	
	const OPT_FTPPORT  = CURLOPT_FTPPORT ;
	
	const OPT_FTP_USE_EPSV  = CURLOPT_FTP_USE_EPSV ;
	
	const OPT_LOW_SPEED_LIMIT  = CURLOPT_LOW_SPEED_LIMIT ;
	
	const OPT_LOW_SPEED_TIME  = CURLOPT_LOW_SPEED_TIME ;
	
	const OPT_RESUME_FROM  = CURLOPT_RESUME_FROM ;
	
	const OPT_COOKIE  = CURLOPT_COOKIE ;
	
	const OPT_SSLCERT  = CURLOPT_SSLCERT ;
	
	const OPT_SSLCERTPASSWD  = CURLOPT_SSLCERTPASSWD ;
	
	const OPT_WRITEHEADER  = CURLOPT_WRITEHEADER ;
	
	const OPT_SSL_VERIFYHOST  = CURLOPT_SSL_VERIFYHOST ;
	
	const OPT_COOKIEFILE  = CURLOPT_COOKIEFILE ;
	
	const OPT_SSLVERSION  = CURLOPT_SSLVERSION ;
	
	const OPT_TIMECONDITION  = CURLOPT_TIMECONDITION ;
	
	const OPT_TIMEVALUE  = CURLOPT_TIMEVALUE ;
	
	const OPT_CUSTOMREQUEST  = CURLOPT_CUSTOMREQUEST ;
	
	const OPT_STDERR  = CURLOPT_STDERR ;
	
	const OPT_TRANSFERTEXT  = CURLOPT_TRANSFERTEXT ;
	
	const OPT_RETURNTRANSFER  = CURLOPT_RETURNTRANSFER ;
	
	const OPT_QUOTE  = CURLOPT_QUOTE ;
	
	const OPT_POSTQUOTE  = CURLOPT_POSTQUOTE ;
	
	const OPT_INTERFACE  = CURLOPT_INTERFACE ;
	
	const OPT_KRB4LEVEL  = CURLOPT_KRB4LEVEL ;
	
	const OPT_HTTPPROXYTUNNEL  = CURLOPT_HTTPPROXYTUNNEL ;
	
	const OPT_FILETIME  = CURLOPT_FILETIME ;
	
	const OPT_WRITEFUNCTION  = CURLOPT_WRITEFUNCTION ;
	
	const OPT_READFUNCTION  = CURLOPT_READFUNCTION ;
	
	const OPT_PASSWDFUNCTION  = CURLOPT_PASSWDFUNCTION ;
	
	const OPT_HEADERFUNCTION  = CURLOPT_HEADERFUNCTION ;
	
	const OPT_MAXREDIRS  = CURLOPT_MAXREDIRS ;
	
	const OPT_MAXCONNECTS  = CURLOPT_MAXCONNECTS ;
	
	const OPT_CLOSEPOLICY  = CURLOPT_CLOSEPOLICY ;
	
	const OPT_FRESH_CONNECT  = CURLOPT_FRESH_CONNECT ;
	
	const OPT_FORBID_REUSE  = CURLOPT_FORBID_REUSE ;
	
	const OPT_RANDOM_FILE  = CURLOPT_RANDOM_FILE ;
	
	const OPT_EGDSOCKET  = CURLOPT_EGDSOCKET ;
	
	const OPT_CONNECTTIMEOUT  = CURLOPT_CONNECTTIMEOUT ;
	
	const OPT_CONNECTTIMEOUT_MS  = CURLOPT_CONNECTTIMEOUT_MS ;
	
	const OPT_SSL_VERIFYPEER  = CURLOPT_SSL_VERIFYPEER ;
	
	const OPT_CAINFO  = CURLOPT_CAINFO ;
	
	const OPT_CAPATH  = CURLOPT_CAPATH ;
	
	const OPT_COOKIEJAR  = CURLOPT_COOKIEJAR ;
	
	const OPT_SSL_CIPHER_LIST  = CURLOPT_SSL_CIPHER_LIST ;
	
	const OPT_BINARYTRANSFER  = CURLOPT_BINARYTRANSFER ;
	
	const OPT_NOSIGNAL  = CURLOPT_NOSIGNAL ;
	
	const OPT_PROXYTYPE  = CURLOPT_PROXYTYPE ;
	
	const OPT_BUFFERSIZE  = CURLOPT_BUFFERSIZE ;
	
	const OPT_HTTPGET  = CURLOPT_HTTPGET ;
	
	const OPT_HTTP_VERSION  = CURLOPT_HTTP_VERSION ;
	
	const OPT_SSLKEY  = CURLOPT_SSLKEY ;
	
	const OPT_SSLKEYTYPE  = CURLOPT_SSLKEYTYPE ;
	
	const OPT_SSLKEYPASSWD  = CURLOPT_SSLKEYPASSWD ;
	
	const OPT_SSLENGINE  = CURLOPT_SSLENGINE ;
	
	const OPT_SSLENGINE_DEFAULT  = CURLOPT_SSLENGINE_DEFAULT ;
	
	const OPT_SSLCERTTYPE  = CURLOPT_SSLCERTTYPE ;
	
	const OPT_CRLF  = CURLOPT_CRLF ;
	
	const OPT_ENCODING  = CURLOPT_ENCODING ;
	
	const OPT_PROXYPORT  = CURLOPT_PROXYPORT ;
	
	const OPT_UNRESTRICTED_AUTH  = CURLOPT_UNRESTRICTED_AUTH ;
	
	const OPT_FTP_USE_EPRT  = CURLOPT_FTP_USE_EPRT ;
	
	const OPT_HTTP200ALIASES  = CURLOPT_HTTP200ALIASES ;
	
	const OPT_HTTPAUTH  = CURLOPT_HTTPAUTH ;
	
	const AUTH_BASIC  = CURLAUTH_BASIC ;
	
	const AUTH_DIGEST  = CURLAUTH_DIGEST ;
	
	const AUTH_GSSNEGOTIATE  = CURLAUTH_GSSNEGOTIATE ;
	
	const AUTH_NTLM  = CURLAUTH_NTLM ;
	
	const AUTH_ANY  = CURLAUTH_ANY ;
	
	const AUTH_ANYSAFE  = CURLAUTH_ANYSAFE ;
	
	const OPT_PROXYAUTH  = CURLOPT_PROXYAUTH ;
	
	const CLOSEPOLICY_LEAST_RECENTLY_USED  = CURLCLOSEPOLICY_LEAST_RECENTLY_USED ;
	
	const CLOSEPOLICY_LEAST_TRAFFIC  = CURLCLOSEPOLICY_LEAST_TRAFFIC ;
	
	const CLOSEPOLICY_SLOWEST  = CURLCLOSEPOLICY_SLOWEST ;
	
	const CLOSEPOLICY_CALLBACK  = CURLCLOSEPOLICY_CALLBACK ;
	
	const CLOSEPOLICY_OLDEST  = CURLCLOSEPOLICY_OLDEST ;

	const TIMECOND_IFMODSINCE  = CURL_TIMECOND_IFMODSINCE ;
	
	const TIMECOND_IFUNMODSINCE  = CURL_TIMECOND_IFUNMODSINCE ;
	
	const TIMECOND_LASTMOD  = CURL_TIMECOND_LASTMOD ;
	
	const VERSION_IPV6  = CURL_VERSION_IPV6 ;
	
	const VERSION_KERBEROS4  = CURL_VERSION_KERBEROS4 ;
	
	const VERSION_SSL  = CURL_VERSION_SSL ;
	
	const VERSION_LIBZ  = CURL_VERSION_LIBZ ;
	
	const VERSION_NOW  = CURLVERSION_NOW ;
	
	const E_OK  = CURLE_OK ;
	
	const E_UNSUPPORTED_PROTOCOL  = CURLE_UNSUPPORTED_PROTOCOL ;
	
	const E_FAILED_INIT  = CURLE_FAILED_INIT ;
	
	const E_URL_MALFORMAT  = CURLE_URL_MALFORMAT ;
	
	const E_URL_MALFORMAT_USER  = CURLE_URL_MALFORMAT_USER ;
	
	const E_COULDNT_RESOLVE_PROXY  = CURLE_COULDNT_RESOLVE_PROXY ;
	
	const E_COULDNT_RESOLVE_HOST  = CURLE_COULDNT_RESOLVE_HOST ;
	
	const E_COULDNT_CONNECT  = CURLE_COULDNT_CONNECT ;
	
	const E_FTP_WEIRD_SERVER_REPLY  = CURLE_FTP_WEIRD_SERVER_REPLY ;
	
	const E_FTP_ACCESS_DENIED  = CURLE_FTP_ACCESS_DENIED ;
	
	const E_FTP_USER_PASSWORD_INCORRECT  = CURLE_FTP_USER_PASSWORD_INCORRECT ;
	
	const E_FTP_WEIRD_PASS_REPLY  = CURLE_FTP_WEIRD_PASS_REPLY ;
	
	const E_FTP_WEIRD_USER_REPLY  = CURLE_FTP_WEIRD_USER_REPLY ;
	
	const E_FTP_WEIRD_PASV_REPLY  = CURLE_FTP_WEIRD_PASV_REPLY ;
	
	const E_FTP_WEIRD_227_FORMAT  = CURLE_FTP_WEIRD_227_FORMAT ;
	
	const E_FTP_CANT_GET_HOST  = CURLE_FTP_CANT_GET_HOST ;
	
	const E_FTP_CANT_RECONNECT  = CURLE_FTP_CANT_RECONNECT ;
	
	const E_FTP_COULDNT_SET_BINARY  = CURLE_FTP_COULDNT_SET_BINARY ;
	
	const E_PARTIAL_FILE  = CURLE_PARTIAL_FILE ;
	
	const E_FTP_COULDNT_RETR_FILE  = CURLE_FTP_COULDNT_RETR_FILE ;
	
	const E_FTP_WRITE_ERROR  = CURLE_FTP_WRITE_ERROR ;
	
	const E_FTP_QUOTE_ERROR  = CURLE_FTP_QUOTE_ERROR ;
	
	const E_HTTP_NOT_FOUND  = CURLE_HTTP_NOT_FOUND ;
	
	const E_WRITE_ERROR  = CURLE_WRITE_ERROR ;
	
	const E_MALFORMAT_USER  = CURLE_MALFORMAT_USER ;
	
	const E_FTP_COULDNT_STOR_FILE  = CURLE_FTP_COULDNT_STOR_FILE ;
	
	const E_READ_ERROR  = CURLE_READ_ERROR ;
	
	const E_OUT_OF_MEMORY  = CURLE_OUT_OF_MEMORY ;
	
	const E_OPERATION_TIMEOUTED  = CURLE_OPERATION_TIMEOUTED ;
	
	const E_FTP_COULDNT_SET_ASCII  = CURLE_FTP_COULDNT_SET_ASCII ;
	
	const E_FTP_PORT_FAILED  = CURLE_FTP_PORT_FAILED ;
	
	const E_FTP_COULDNT_USE_REST  = CURLE_FTP_COULDNT_USE_REST ;
	
	const E_FTP_COULDNT_GET_SIZE  = CURLE_FTP_COULDNT_GET_SIZE ;
	
	const E_HTTP_RANGE_ERROR  = CURLE_HTTP_RANGE_ERROR ;
	
	const E_HTTP_POST_ERROR  = CURLE_HTTP_POST_ERROR ;
	
	const E_SSL_CONNECT_ERROR  = CURLE_SSL_CONNECT_ERROR ;
	
	const E_FTP_BAD_DOWNLOAD_RESUME  = CURLE_FTP_BAD_DOWNLOAD_RESUME ;
	
	const E_FILE_COULDNT_READ_FILE  = CURLE_FILE_COULDNT_READ_FILE ;
	
	const E_LDAP_CANNOT_BIND  = CURLE_LDAP_CANNOT_BIND ;
	
	const E_LDAP_SEARCH_FAILED  = CURLE_LDAP_SEARCH_FAILED ;
	
	const E_LIBRARY_NOT_FOUND  = CURLE_LIBRARY_NOT_FOUND ;
	
	const E_FUNCTION_NOT_FOUND  = CURLE_FUNCTION_NOT_FOUND ;
	
	const E_ABORTED_BY_CALLBACK  = CURLE_ABORTED_BY_CALLBACK ;
	
	const E_BAD_FUNCTION_ARGUMENT  = CURLE_BAD_FUNCTION_ARGUMENT ;
	
	const E_BAD_CALLING_ORDER  = CURLE_BAD_CALLING_ORDER ;
	
	const E_HTTP_PORT_FAILED  = CURLE_HTTP_PORT_FAILED ;
	
	const E_BAD_PASSWORD_ENTERED  = CURLE_BAD_PASSWORD_ENTERED ;
	
	const E_TOO_MANY_REDIRECTS  = CURLE_TOO_MANY_REDIRECTS ;
	
	const E_UNKNOWN_TELNET_OPTION  = CURLE_UNKNOWN_TELNET_OPTION ;
	
	const E_TELNET_OPTION_SYNTAX  = CURLE_TELNET_OPTION_SYNTAX ;
	
	const E_OBSOLETE  = CURLE_OBSOLETE ;
	
	const E_SSL_PEER_CERTIFICATE  = CURLE_SSL_PEER_CERTIFICATE ;
	
	const E_GOT_NOTHING  = CURLE_GOT_NOTHING ;
	
	const E_SSL_ENGINE_NOTFOUND  = CURLE_SSL_ENGINE_NOTFOUND ;
	
	const E_SSL_ENGINE_SETFAILED  = CURLE_SSL_ENGINE_SETFAILED ;
	
	const E_SEND_ERROR  = CURLE_SEND_ERROR ;
	
	const E_RECV_ERROR  = CURLE_RECV_ERROR ;
	
	const E_SHARE_IN_USE  = CURLE_SHARE_IN_USE ;
	
	const E_SSL_CERTPROBLEM  = CURLE_SSL_CERTPROBLEM ;
	
	const E_SSL_CIPHER  = CURLE_SSL_CIPHER ;
	
	const E_SSL_CACERT  = CURLE_SSL_CACERT ;
	
	const E_BAD_CONTENT_ENCODING  = CURLE_BAD_CONTENT_ENCODING ;
	
	const E_LDAP_INVALID_URL  = CURLE_LDAP_INVALID_URL ;
	
	const E_FILESIZE_EXCEEDED  = CURLE_FILESIZE_EXCEEDED ;
	
	const E_FTP_SSL_FAILED  = CURLE_FTP_SSL_FAILED ;
	
	const FTPAUTH_DEFAULT  = CURLFTPAUTH_DEFAULT ;
	// ^ Available since PHP 5.1.0 
	
	const FTPAUTH_SSL  = CURLFTPAUTH_SSL ;
	// ^ Available since PHP 5.1.0 
	
	const FTPAUTH_TLS  = CURLFTPAUTH_TLS ;
	// ^ Available since PHP 5.1.0 
	
	const PROXY_HTTP  = CURLPROXY_HTTP ;
	
	const PROXY_SOCKS5  = CURLPROXY_SOCKS5 ;
	
	const NETRC_OPTIONAL  = CURL_NETRC_OPTIONAL ;
	
	const NETRC_IGNORED  = CURL_NETRC_IGNORED ;
	
	const NETRC_REQUIRED  = CURL_NETRC_REQUIRED ;
	
	const HTTP_VERSION_NONE  = CURL_HTTP_VERSION_NONE ;
	
	const HTTP_VERSION_1_0  = CURL_HTTP_VERSION_1_0 ;
	
	const HTTP_VERSION_1_1  = CURL_HTTP_VERSION_1_1 ;
	
	const M_CALL_MULTI_PERFORM  = CURLM_CALL_MULTI_PERFORM ;
	
	const M_OK  = CURLM_OK ;
	
	const M_BAD_HANDLE  = CURLM_BAD_HANDLE ;
	
	const M_BAD_EASY_HANDLE  = CURLM_BAD_EASY_HANDLE ;
	
	const M_OUT_OF_MEMORY  = CURLM_OUT_OF_MEMORY ;
	
	const M_INTERNAL_ERROR  = CURLM_INTERNAL_ERROR ;
	
	const MSG_DONE  = CURLMSG_DONE ;
		
	
}